package br.academia.arq.dao;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;

import org.hibernate.HibernateException;
import org.hibernate.Query;

import br.academia.arq.erros.DAOException;
import br.academia.dominio.Movimentacao;
import br.academia.util.Validador;


/**
 * Dao com operações referentes a Movimentacao
 * @see Movimentacao
 */
public class MovimentacaoDAO extends GenericDAO{
	
	/**
	 * Método que retorna uma entidade do classe Movimentacao que possua o
	 * nome idêntico ao nome passado como parâmetro
	 * @param nome
	 * @return
	 * @throws HibernateException
	 * @throws DAOException
	 */
	public Movimentacao findMovimentacaoByDescricao(String descricao) throws HibernateException, DAOException{
		String hql = "select m from Movimentacao m where m.descricao = :descricao ";
		
		Query q = getSession().createQuery(hql);
		
		q.setParameter("descricao", descricao);
		
		Movimentacao movimentacao = (Movimentacao) q.uniqueResult();
		
		return movimentacao;
	}
	
	/**
	 * Método que retorna itens que tenham nome ou descrição parecidos
	 * com os itens do ideal passado como parâmetro
	 * @param ideal
	 * @return
	 * @throws HibernateException
	 * @throws DAOException
	 */
	public Collection<Movimentacao> findMovimentacaoEntreDatas(Movimentacao movimentacao, Date dataInicio, Date dataFim) throws HibernateException, DAOException{
		String hql = "select m from Movimentacao m where 1 = 1 ";
		HashMap<String, Object> parametros = new HashMap<String, Object>();
			
		if(!Validador.isEmpty(movimentacao.getDescricao())){
			hql += " and m.descricao like :descricao ";
			parametros.put("descricao", "%" + movimentacao.getDescricao() + "%");
		}
		
		if(!Validador.isEmpty(movimentacao.getEntrada())){
			hql += " and m.entrada = :entrada ";
			parametros.put("entrada", movimentacao.getEntrada());
		}
		
		if(!Validador.isEmpty(movimentacao.getValor())){
			hql += " and m.valor = :valor ";
			parametros.put("valor", movimentacao.getValor());
		}
		
		if(!Validador.isEmpty(dataInicio) || !Validador.isEmpty(dataFim)){
			if(!Validador.isEmpty(dataInicio) && !Validador.isEmpty(dataFim)){
				hql += " and m.dataFaturamento between :dataInicio and :dataFim ";
				parametros.put("dataFim", dataFim);
				parametros.put("dataInicio", dataInicio);
			}else if(!Validador.isEmpty(dataInicio)){
				hql += " and m.dataFaturamento >= :dataInicio ";
				parametros.put("dataInicio", dataInicio);
			}else if(!Validador.isEmpty(dataFim)){
				hql += " and m.dataFaturamento <= :dataFim ";
				parametros.put("dataFim", dataFim);
			}
		}
		
		Query q = getSession().createQuery(hql);
		
		setParametros(parametros, q);
		
		@SuppressWarnings("unchecked")
		Collection<Movimentacao> movimentacoes = q.list();
		
		return movimentacoes;
	}
	
	/**
	 * Método que retorna itens que tenham nome ou descrição parecidos
	 * com os itens do ideal passado como parâmetro
	 * @param ideal
	 * @return
	 * @throws HibernateException
	 * @throws DAOException
	 */
	public Collection<Movimentacao> findMovimentacaoLike(Movimentacao movimentacao) throws HibernateException, DAOException{
		String hql = "select m from Movimentacao m where 1 = 1 ";
		HashMap<String, Object> parametros = new HashMap<String, Object>();
			
		if(!Validador.isEmpty(movimentacao.getDescricao())){
			hql += " and m.descricao like :descricao ";
			parametros.put("descricao", "%" + movimentacao.getDescricao() + "%");
		}
		
		if(!Validador.isEmpty(movimentacao.getEntrada())){
			hql += " and m.entrada = :entrada ";
			parametros.put("entrada", movimentacao.getEntrada());
		}
		
		if(!Validador.isEmpty(movimentacao.getDataFaturamento())){
			hql += " and m.dataFaturamento = :dataFaturamento ";
			parametros.put("dataFaturamento", movimentacao.getDataFaturamento());
		}
		
		if(!Validador.isEmpty(movimentacao.getValor())){
			hql += " and m.valor = :valor ";
			parametros.put("valor", movimentacao.getValor());
		}
		
		Query q = getSession().createQuery(hql);
		
		setParametros(parametros, q);
		
		@SuppressWarnings("unchecked")
		Collection<Movimentacao> movimentacoes = q.list();
		
		return movimentacoes;
	}
}
